package com.seari.monitor.impl;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.seari.bean.BaseTaskBean;
import com.seari.main.TaskRunner;
import com.seari.monitor.MiddlewareMonitor;
import com.seari.utils.JedisPoolUtils;
import com.seari.utils.LoadPropertiesUtils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisConnectionException;

public class RedisMiddlewareMonitor extends MiddlewareMonitor {

	final static Logger logger = LoggerFactory.getLogger(RedisMiddlewareMonitor.class);
	private static final long TIME_INTERVAL = 2 * 60 * 1000;
	private static final String MIDWARE_NAME ="redis";
	private static AtomicBoolean initState = new AtomicBoolean(false); 
	public static ExecutorService redisExecutor = Executors.newCachedThreadPool();
	

	@Override
	public boolean isClient() {
		boolean f = true;
		Jedis jedis = null;
		try {
			jedis = JedisPoolUtils.getJedis();
		} catch (JedisConnectionException e) {
			return false;
		} finally {
			if(f) {
				jedis.close();
			}
		}
		return true;
	}

	@Override
	public void monitorData() {
		
		super.startService(MIDWARE_NAME);
		
		Set<String> redisDBKeys = getRedisDBKeys();    //获取redis中的key:项目
		if (redisDBKeys != null && redisDBKeys.size() != 0) {
			for (String key : redisDBKeys) {
				redisExecutor.submit(new Runnable() {
					@Override
					public void run() {
						logger.info("分发线程监控 ：" + key);
						redisMonitorData(key);
					}
				});
			}
		}
		
		

	}

	
	/**
	 * 监控redis数据是否超时
	 * @param key
	 */
	public void redisMonitorData(String key) {
		
		Jedis jedis = null;
		BaseTaskBean base = new BaseTaskBean();
		try {
			initState.set(false);
			jedis = JedisPoolUtils.getJedis();
			Map<String, String> item = LoadPropertiesUtils.getItemDescription(key);
			if(item == null || item.size() == 0) {
				logger.info(key + " 无此配置...");
				return;
			}
			base.setTaskName(item.get("item"));
			base.setScriptPath(item.get("scriptPath"));
			while (true) {
				if(jedis == null) {
					logger.info(base.getTaskName() + " 项目jedis连接失败,执行重启Redis服务");
					this.restart();
					jedis = JedisPoolUtils.getJedis();
					continue;
				}
				logger.info("开始监控 :" + base.getTaskName());
				String data = jedis.get(key);
				String[] splitData = data.split(",");
				if (splitData[0].equals("stop")) {
					break;
				}
				long timeNow = System.currentTimeMillis();
				long dataTime = Long.valueOf(splitData[1]);
				if (timeNow - dataTime > TIME_INTERVAL) {
					logger.info(base.getTaskName() + " 数据超时,开始重启项目");
					TaskRunner task = new TaskRunner(base);
					task.run();
				}
				
				TimeUnit.SECONDS.sleep(20);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (JedisConnectionException e) {
			restart();
			redisMonitorData(key);
		} catch (Exception e) {
			logger.error(base.getTaskName() + "项目监控出错");
		} finally {
			jedis.close();
		}
	}
	
	
	/**
	 * 获取 redis key
	 * @return
	 */
	public Set<String> getRedisDBKeys(){
		Jedis jedis = null;
		boolean f = true;
		try {
			jedis = JedisPoolUtils.getJedis();
			if(jedis == null) {
				f = false;
				return null;
			}
			Set<String> keys = jedis.keys("*");
			return keys;
		} finally {
			if(f) {
				jedis.close();
			}
		} 
	}
	
	
	/**
	 * 重启redis服务
	 */
	public synchronized void restart() {
		if(!initState.compareAndSet(false, true)) {
			try {
				TimeUnit.SECONDS.sleep(3);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return;
		}
		logger.info("重启Redis服务");
		super.restartService(MIDWARE_NAME,3);
	}
	
	
	public static void main(String[] args) {
	}

}
